#!/usr/bin/env node

require('dotenv').config();
const Client = require('ftp');
const chalk = require('chalk');
const net = require('net');

class ForceActiveTest {
    constructor() {
        this.host = process.env.FTP_HOST;
        this.port = parseInt(process.env.FTP_PORT) || 21;
        this.user = process.env.FTP_USER;
        this.password = process.env.FTP_PASSWORD;
    }

    async testForceActive() {
        console.log(chalk.blue('🔧 强制主动模式测试'));
        console.log(chalk.gray('=' .repeat(40)));
        
        return new Promise((resolve) => {
            const client = new Client();
            
            // 重写passive属性和相关方法，强制主动模式
            const originalPasv = client._pasv;
            client._pasv = () => {
                console.log(chalk.yellow('⚠️ 阻止PASV命令，强制使用PORT'));
                // 直接返回false，阻止被动模式
                return false;
            };
            
            // 监听所有发送的命令
            const originalSend = client._send;
            client._send = function(cmd, cb) {
                if (cmd.startsWith('PASV')) {
                    console.log(chalk.red('🚫 阻止PASV命令'));
                    // 改为PORT命令
                    this._port(cb);
                    return;
                }
                console.log(chalk.gray(`📤 发送命令: ${cmd}`));
                return originalSend.call(this, cmd, cb);
            };

            client.on('ready', () => {
                console.log(chalk.green('✓ 连接建立'));
                
                // 手动测试PORT命令
                this.testManualPort(client, resolve);
            });

            client.on('error', (err) => {
                console.log(chalk.red(`❌ 连接错误: ${err.message}`));
                resolve(false);
            });

            client.connect({
                host: this.host,
                port: this.port,
                user: this.user,
                password: this.password,
                passive: false,  // 明确设置为false
                connTimeout: 20000
            });
        });
    }

    async testManualPort(client, resolve) {
        console.log(chalk.blue('手动测试PORT命令...'));
        
        // 创建本地监听端口
        const server = net.createServer((socket) => {
            console.log(chalk.green('✓ 收到数据连接'));
            socket.on('data', (data) => {
                console.log(chalk.cyan(`接收数据: ${data.length} 字节`));
            });
            socket.on('end', () => {
                console.log(chalk.yellow('数据连接结束'));
            });
        });

        server.listen(0, '0.0.0.0', () => {
            const localPort = server.address().port;
            console.log(chalk.cyan(`本地监听端口: ${localPort}`));

            // 获取本地IP
            this.getLocalIP().then(localIP => {
                console.log(chalk.cyan(`本地IP: ${localIP}`));

                const ip1 = parseInt(localIP.split('.')[0]);
                const ip2 = parseInt(localIP.split('.')[1]);
                const ip3 = parseInt(localIP.split('.')[2]);
                const ip4 = parseInt(localIP.split('.')[3]);
                const portHigh = Math.floor(localPort / 256);
                const portLow = localPort % 256;

                const portCmd = `PORT ${ip1},${ip2},${ip3},${ip4},${portHigh},${portLow}`;
                console.log(chalk.gray(`PORT命令: ${portCmd}`));

                // 发送PORT命令
                client._send(portCmd, (err, text, code) => {
                    if (err) {
                        console.log(chalk.red(`❌ PORT失败: ${err.message}`));
                        server.close();
                        resolve(false);
                        return;
                    }

                    console.log(chalk.green(`✓ PORT成功: ${text}`));

                    // 现在尝试上传文件
                    const fs = require('fs');
                    const testContent = 'Active mode test file';
                    fs.writeFileSync('./active-test.txt', testContent);

                    // 发送STOR命令
                    client._send('STOR /active-test.txt', (storErr, storText, storCode) => {
                        if (storErr) {
                            console.log(chalk.red(`❌ STOR失败: ${storErr.message}`));
                        } else {
                            console.log(chalk.green(`✓ STOR响应: ${storText}`));
                        }

                        server.close();
                        resolve(!storErr);
                    });
                });
            });
        });
    }

    async getLocalIP() {
        const { networkInterfaces } = require('os');
        const nets = networkInterfaces();
        
        for (const name of Object.keys(nets)) {
            for (const net of nets[name]) {
                if (net.family === 'IPv4' && !net.internal) {
                    return net.address;
                }
            }
        }
        return '127.0.0.1';
    }

    // 尝试使用不同的FTP库
    async testAlternativeLibrary() {
        console.log(chalk.yellow('\n尝试基础socket实现...'));
        
        return new Promise((resolve) => {
            const socket = net.createConnection(this.port, this.host);
            
            socket.on('connect', () => {
                console.log(chalk.green('✓ Socket连接成功'));
                
                socket.on('data', (data) => {
                    console.log(chalk.gray(`收到: ${data.toString().trim()}`));
                    
                    const response = data.toString().trim();
                    if (response.startsWith('220')) {
                        // 发送用户名
                        socket.write(`USER ${this.user}\r\n`);
                    } else if (response.startsWith('331')) {
                        // 发送密码
                        socket.write(`PASS ${this.password}\r\n`);
                    } else if (response.startsWith('230')) {
                        console.log(chalk.green('✓ 登录成功'));
                        // 尝试PORT命令
                        socket.write('PORT 127,0,0,1,200,1\r\n');
                    } else if (response.startsWith('200') && response.includes('PORT')) {
                        console.log(chalk.green('✓ PORT命令成功'));
                        resolve(true);
                        socket.end();
                        return;
                    }
                });
            });

            socket.on('error', (err) => {
                console.log(chalk.red(`❌ Socket错误: ${err.message}`));
                resolve(false);
            });

            setTimeout(() => {
                socket.end();
                resolve(false);
            }, 15000);
        });
    }
}

if (require.main === module) {
    const test = new ForceActiveTest();
    
    test.testForceActive()
        .then(success => {
            if (!success) {
                return test.testAlternativeLibrary();
            }
            return success;
        })
        .then(finalSuccess => {
            console.log(finalSuccess ? 
                chalk.green('\n✅ 找到可工作的方案!') : 
                chalk.red('\n❌ 所有方案都失败了')
            );
            process.exit(finalSuccess ? 0 : 1);
        })
        .catch(console.error);
}

module.exports = ForceActiveTest;